package com.hroze.util.web;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.log4j.Logger;

public class WebTool {
	static Logger log = Logger.getLogger(WebTool.class);

	/**
	 * url转码
	 * 
	 * @param request
	 * @param enc
	 */
	public static void decodeParams(HttpServletRequest request, String enc) {
		Map<String, String[]> paramsMap = request.getParameterMap();
		for (String key : paramsMap.keySet()) {
			log.debug(key);

			String[] value = paramsMap.get(key);
			log.debug(value);
			if (value.length <= 0)
				continue;
			for (int i = 0; i < value.length; i++) {
				String v = value[i];
				log.debug(v);
				try {
					v = java.net.URLDecoder.decode(v, enc);
					log.debug(v);
					value[i] = v;
				} catch (UnsupportedEncodingException e) {
					log.error("参数转码出错：", e);
				}
			}
		}
	}

	/**
	 * 获取参数列表(自动去空参数)
	 * 
	 * @param request
	 * @return
	 */
	public static Map<String, String> getParamsMap(HttpServletRequest request) {
		Map<String, String[]> paramsMap = request.getParameterMap();
		Map<String, String> argsMap = new HashMap<String, String>();
		for (String key : paramsMap.keySet()) {
			String value = StringUtils.join(paramsMap.get(key));
			if (value.length() <= 0)
				continue;
			argsMap.put(genName(key), value);
		}
		return argsMap;
	}

	/**
	 * 取请求全部参数
	 * 
	 * @param request
	 * @return
	 */
	public static Map<String, String> getMap(HttpServletRequest request) {
		HashMap<String, String> map = new HashMap<String, String>();
		Enumeration names = request.getParameterNames();
		while (names.hasMoreElements()) {
			String name = (String) names.nextElement();
			String[] a = request.getParameterValues(name);
			String value = "";
			if (a != null && a.length > 0) {
				value = StringUtils.join(a, ",");
			}
			map.put(name, value);
		}
		return map;
	}

	/**
	 * 处理参数中的'_'和'-'间隔符 例如：your_name-frist -->yourNameFrist
	 * 
	 * @param name
	 * @return
	 */
	public static String genName(String name) {
		String c = WordUtils.capitalize(name, new char[] { '_' });
		c = WordUtils.capitalize(c, new char[] { '-' });
		c = StringUtils.remove(c, '_');
		c = StringUtils.remove(c, '-');
		c = StringUtils.uncapitalize(c);
		return c;
	}

	public static void main(String[] args) {
		String str = "a_dd";
		System.out.println(genName(str));
	}

	/**
	 * 
	 * 使用方法
	 * 
	 * InfoBean bean = RequestDataBinder.bind(request,InfoBean.class);
	 * 
	 * @param request
	 *            HttpServletRequest
	 * @param clazz
	 *            需要的javabean的class
	 * @return
	 */
	public static <B> B bind(HttpServletRequest request, Class<B> clazz) {
		RequestWrapper requestWrapper = new RequestWrapper(request);
		Object res = null;
		try {
			res = clazz.newInstance();
			// 取得所有field
			Field[] fields = clazz.getDeclaredFields();
			for (int i = 0; fields != null && i < fields.length; i++) {
				Field aField = fields[i];
				// 如果是staitc或者final类型的变量，不设值
				if (Modifier.isStatic(aField.getModifiers())
						|| Modifier.isFinal(aField.getModifiers())) {
					continue;
				}
				// 设置字段可访问为true
				aField.setAccessible(true);
				// 取得字段类型
				Class fieldType = aField.getType();
				boolean isArrayField = fieldType.isArray();
				// 设置值
				if (isArrayField) {
					Class comType = fieldType.getComponentType();
					String[] values = requestWrapper.getParameterValues(aField
							.getName());
					Object objs = Array.newInstance(comType, values.length);
					for (int k = 0, count = values.length; k < count; k++) {
						Array.set(objs, k, convert(values[k], comType));
					}
					aField.set(res, objs);
				} else {
					aField.set(res, convert(requestWrapper.getParameter(aField
							.getName()), fieldType));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return clazz.cast(res);
	}

	/**
	 * 数据类型格式化(日期，Integer,String,boolean)
	 * 
	 * @param value
	 * @param type
	 * @return
	 */
	private static Object convert(String value, Class type) {
		try {
			if (type.equals(Date.class)) {
				SimpleDateFormat format = new SimpleDateFormat(
						"yyyy-MM-dd hh:mm:ss");
				return format.parse(value);
			} else if (type.equals(int.class) || type.equals(Integer.class)) {
				int res = 0;
				try {
					res = Integer.parseInt(value);
				} catch (NumberFormatException e) {
					Logger.getRootLogger().error("提取数字参数出错，使用0作为默认值", e);
				}
				return res;

			} else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
				return Boolean.parseBoolean(value);
			} else if (type.equals(Double.class) || type.equals(double.class)) {
				return Double.parseDouble(value);
			} else if (type.equals(float.class) || type.equals(Float.class)) {
				return Float.parseFloat(value);
			} else if (type.equals(byte.class) || type.equals(Byte.class)) {
				return Byte.parseByte(value);
			} else if (type.equals(String.class)) {
				return value;
			} else {
				Logger.getRootLogger().error(
						"出现未知类型：" + type.getName() + "，参数值为：" + value
								+ ",最终设置为null");
				return null;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			return ex;
		}

	}

	/**
	 * HttpServletRequest 代理类
	 * 
	 * @author Administrator
	 * 
	 */
	private static class RequestWrapper {
		private HttpServletRequest request;

		private RequestWrapper(HttpServletRequest request) {
			this.request = request;
		}

		/**
		 * 字段名称
		 * 
		 * @param para
		 * @return
		 */
		public String getParameter(String para) {
			return nvl(request.getParameter(para));
		}
		/**
		 * 获得参数值数组
		 * @param arg0
		 * @return
		 */
		public String[] getParameterValues(String arg0) {
			String[] tmp = request.getParameterValues(arg0);
			if (tmp == null) {
				return new String[0];
			} else {
				for (int i = 0, count = tmp.length; i < count; i++) {
					tmp[i] = nvl(tmp[i]);
				}
				return tmp;
			}
		}

		/**
		 * HttpServletRequest 代理 去null 做trim 操作
		 * 
		 * @param request
		 * @return
		 */
		public static RequestWrapper proxyHttpServletRequest(
				HttpServletRequest request) {
			return new RequestWrapper(request);
		}

		/**
		 * 去除null trim
		 * 
		 * @param obj
		 * @return
		 */
		private String nvl(Object obj) {

			if (null == obj) {
				return "";
			} else {
				return obj.toString().trim();
			}
		}
	}

}
